package com.gobang.modules.match;

import com.gobang.entity.User;
import com.gobang.modules.game.GameService;
import com.gobang.modules.message.MessageService;
import com.gobang.modules.room.Room;
import com.gobang.proto.GameProto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 匹配服务
 */
@Slf4j
@Service
public class MatchService {

    @Autowired
    private GameService gameService;
    @Autowired
    private MessageService messageService;

    // 匹配队列
    private final LinkedBlockingQueue<User> matchQueue = new LinkedBlockingQueue<>();
    
    // 匹配中的玩家
    private final Map<Long, User> matchingPlayers = new ConcurrentHashMap<>();

    // 匹配定时器
    private ScheduledExecutorService matchScheduler;

    @PostConstruct
    public void init() {
        // 启动匹配定时任务
        matchScheduler = Executors.newScheduledThreadPool(1);
        matchScheduler.scheduleAtFixedRate(this::processMatching, 1, 1, TimeUnit.SECONDS);
        log.info("匹配服务已启动");
    }

    @PreDestroy
    public void destroy() {
        if (matchScheduler != null) {
            matchScheduler.shutdown();
            log.info("匹配服务已关闭");
        }
    }

    /**
     * 加入匹配队列
     */
    public synchronized MatchResponse joinMatch(User user) {
        if (matchingPlayers.containsKey(user.getId())) {
            return MatchResponse.newBuilder()
                    .setSuccess(false)
                    .setMessage("已在匹配队列中")
                    .build();
        }
        
        matchingPlayers.put(user.getId(), user);
        matchQueue.offer(user);
        log.info("玩家加入匹配: userId={}, username={}", user.getId(), user.getUsername());
        
        return MatchResponse.newBuilder()
                .setSuccess(true)
                .setMessage("已加入匹配队列")
                .build();
    }

    /**
     * 取消匹配
     */
    public synchronized void cancelMatch(Long userId) {
        User user = matchingPlayers.remove(userId);
        if (user != null) {
            matchQueue.remove(user);
            log.info("玩家取消匹配: userId={}", userId);
        }
    }

    /**
     * 检查玩家是否在匹配中
     */
    public boolean isMatching(Long userId) {
        return matchingPlayers.containsKey(userId);
    }
    
    /**
     * 获取匹配队列大小
     */
    public int getMatchQueueSize() {
        return matchQueue.size();
    }

    /**
     * 尝试匹配
     * @return 匹配成功的两个玩家，如果没有匹配成功返回null
     */
    private synchronized User[] tryMatch() {
        if (matchQueue.size() < 2) {
            return null;
        }
        
        User player1 = matchQueue.poll();
        User player2 = matchQueue.poll();
        
        if (player1 != null && player2 != null) {
            matchingPlayers.remove(player1.getId());
            matchingPlayers.remove(player2.getId());
            
            log.info("匹配成功: player1={}, player2={}", player1.getUsername(), player2.getUsername());
            
            return new User[]{player1, player2};
        }
        
        // 如果匹配失败，放回队列
        if (player1 != null) {
            matchQueue.offer(player1);
        }
        if (player2 != null) {
            matchQueue.offer(player2);
        }
        
        return null;
    }

    /**
     * 处理匹配逻辑
     */
    private void processMatching() {
        try {
            User[] players = tryMatch();
            if (players != null && players.length == 2) {
                User player1 = players[0];
                User player2 = players[1];

                // 创建游戏房间
                Room room = gameService.createGame(
                        player1.getId(), player1.getUsername(),
                        player2.getId(), player2.getUsername()
                );

                // 发送匹配成功消息
                MatchSuccess matchSuccess1 = MatchSuccess.newBuilder()
                        .setGameId(room.getGameId())
                        .setBlackPlayerId(player1.getId())
                        .setBlackPlayerName(player1.getUsername())
                        .setWhitePlayerId(player2.getId())
                        .setWhitePlayerName(player2.getUsername())
                        .setYourColor(PieceColor.BLACK)
                        .build();

                MatchSuccess matchSuccess2 = MatchSuccess.newBuilder()
                        .setGameId(room.getGameId())
                        .setBlackPlayerId(player1.getId())
                        .setBlackPlayerName(player1.getUsername())
                        .setWhitePlayerId(player2.getId())
                        .setWhitePlayerName(player2.getUsername())
                        .setYourColor(PieceColor.WHITE)
                        .build();

                messageService.sendToPlayer(player1.getId(), MessageType.MATCH_SUCCESS, matchSuccess1.toByteArray());
                messageService.sendToPlayer(player2.getId(), MessageType.MATCH_SUCCESS, matchSuccess2.toByteArray());

                // 发送游戏开始消息
                GameStart gameStart = GameStart.newBuilder()
                        .setGameId(room.getGameId())
                        .setCurrentTurn(PieceColor.BLACK)
                        .setCurrentPlayerId(player1.getId())
                        .build();

                messageService.sendToPlayer(player1.getId(), MessageType.GAME_START, gameStart.toByteArray());
                messageService.sendToPlayer(player2.getId(), MessageType.GAME_START, gameStart.toByteArray());

                log.info("匹配成功: player1={}, player2={}, roomId={}", 
                        player1.getUsername(), player2.getUsername(), room.getRoomId());
            }
        } catch (Exception e) {
            log.error("处理匹配失败", e);
        }
    }
}
